package auctionhaus

import org.springframework.dao.DataIntegrityViolationException
import grails.plugins.springsecurity.Secured
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import grails.plugins.springsecurity.SpringSecurityService
import java.text.DecimalFormat

class ListingController {

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

    def listingCreateService

    def springSecurityService

    def index() {
        redirect(action: "list", params: params)
    }

    def list() {
        params.max = Math.min(params.max ? params.int('max') : 5, 100)

        if (!params.sort)
        {
            params.sort = "dateCreated"
            params.order = "desc"
        }

        [listingInstanceList: Listing.findAllByEndDateTimeGreaterThan(new Date(),params), listingInstanceTotal: Listing.count()]

    }
    
    @Secured(['ROLE_USER'])
    def listMine()
    {
        params.max = Math.min(params.max ? params.int('max') : 5, 100)

        if (!params.sort)
        {
            params.sort = "dateCreated"
            params.order = "desc"
        }

        Customer customer = springSecurityService.currentUser
        def myListingsFirstScreen = Listing.findAllBySeller(customer, params)
        def myListingsTotalSize = Listing.findAllBySeller(customer).size()

        render(view: "list", model: [listingInstanceList: myListingsFirstScreen, listingInstanceTotal: myListingsTotalSize, listingInstanceMine: true])
    }

    @Secured(['ROLE_USER'])
    def create() {
        [listingInstance: new Listing(params)]
    }

    @Secured(['ROLE_USER'])
    def save() {

        Listing l = listingCreateService.createListing(params)
        if (l.hasErrors())
        {
            render(view: "create", model: [listingInstance: l])
        }
        else
        {
            flash.message = message(code: 'default.created.message', args: [message(code: 'listing.label', default: 'Listing'), l.id])
            redirect(action: "listMine", id: l.id)
        }
    }

    def show() {
        def listingInstance = Listing.get(params.id)
        if (!listingInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "list")
            return
        }
        
        Date now = new Date()
        if (listingInstance.endDateTime < now){
            flash.message = message(code: 'listing.expired', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "list")
            return
        }
        [listingInstance: listingInstance]
    }
    
    def showBids() {
        StringBuffer result = new StringBuffer()
        def listingInstance = Listing.get(params.id)
        def bidList = Bid.bidsByListing(listingInstance).list()
        DecimalFormat dec = new DecimalFormat("###.##");
        dec.setMinimumFractionDigits(2)

        ListIterator li = bidList.listIterator(bidList.size());
        int count=1
        while (li.hasPrevious()) {
            if (count < 11){
                Bid bid = li.previous()
                result.append("<span class=\"property-value\" aria-labelledby=\"bids-label\">")
                result.append(" Bid")
                        .append(" Amount: \$" )
                        .append(dec.format(bid.amount).toString())
                        .append(" Bidder: ")
                        .append(bid.bidder.email.substring(0,listingInstance?.seller?.email?.indexOf("@")))
                        .append(" Date/Time: ").append(bid.bidDateTime.toString())
                result.append("</span>")
                count++
            }
            else{
                break
            }
        }
        render(text: result.toString(), contentType: "text/html", encoding: "utf-8")
    }

    def showMinimumBid() {
        StringBuffer result = new StringBuffer()
        def listingInstance = Listing.get(params.id)
        float increment = 0.5f
        float minimumBid = listingInstance.getMinimumBid()
        if (minimumBid < increment){
            minimumBid = listingInstance.currentBid + increment
        }
        DecimalFormat dec = new DecimalFormat("###.##");
        dec.setMinimumFractionDigits(2)
        render(text: "\$" + dec.format(minimumBid).toString(), contentType: "text/html", encoding: "utf-8")
    }

    @Secured(['ROLE_ADMIN'])
    def edit() {
        def listingInstance = Listing.get(params.id)
        if (!listingInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "list")
            return
        }

        [listingInstance: listingInstance]
    }

    @Secured(['ROLE_ADMIN'])
    def update() {
        def listingInstance = Listing.get(params.id)
        if (!listingInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "list")
            return
        }

        if (params.version) {
            def version = params.version.toLong()
            if (listingInstance.version > version) {
                listingInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                        [message(code: 'listing.label', default: 'Listing')] as Object[],
                        "Another user has updated this Listing while you were editing")
                render(view: "edit", model: [listingInstance: listingInstance])
                return
            }
        }

        listingInstance.properties = params

        if (!listingInstance.save(flush: true)) {
            render(view: "edit", model: [listingInstance: listingInstance])
            return
        }

        flash.message = message(code: 'default.updated.message', args: [message(code: 'listing.label', default: 'Listing'), listingInstance.id])
        redirect(action: "show", id: listingInstance.id)
    }

    @Secured(['ROLE_ADMIN'])
    def delete() {
        def listingInstance = Listing.get(params.id)
        if (!listingInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "list")
            return
        }

        try {
            listingInstance.delete(flush: true)
            flash.message = message(code: 'default.deleted.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "list")
        }
        catch (DataIntegrityViolationException e) {
            flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "show", id: params.id)
        }
    }
}
